home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
wb
/
czesc_1
/
cgwbpattern101
/
ilbmtoppm.lha
/
src
/
libcmap2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-16
|
6KB
|
239 lines
/* libcmap2.c - support routines for color rows
**
** Copyright (C) 1994 Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
#include "ppmcmap2.h"
colorhash_table
ppm_colorrowtocolorhash(colorrow, ncolors)
pixel *colorrow;
int ncolors;
{
colorhash_table cht;
int i;
cht = ppm_alloccolorhash();
for( i = 0; i < ncolors; i++ ) {
if( ppm_lookupcolor(cht, &colorrow[i]) < 0 ) {
if( ppm_addtocolorhash(cht, &colorrow[i], i) < 0 )
pm_error("out of memory adding to hash table");
}
}
return cht;
}
pixel *
ppm_computecolorrow(pixels, cols, rows, maxcolors, ncolorsP)
pixel **pixels;
int cols, rows, maxcolors;
int *ncolorsP;
{
int ncolors, row, col;
colorhash_table cht;
pixel *pixrow;
pixrow = ppm_allocrow(maxcolors);
cht = ppm_alloccolorhash(); ncolors = 0;
for( row = 0; row < rows; row++ ) {
for( col = 0; col < cols; col++ ) {
if( ppm_lookupcolor(cht, &pixels[row][col]) < 0 ) {
if( ncolors >= maxcolors ) {
ppm_freerow(pixrow);
pixrow = (pixel *)0;
ncolors = -1;
goto fail;
}
if( ppm_addtocolorhash(cht, &pixels[row][col], ncolors) < 0 )
pm_error("out of memory adding to hash table");
pixrow[ncolors] = pixels[row][col];
++ncolors;
}
}
}
fail:
ppm_freecolorhash(cht);
*ncolorsP = ncolors;
return pixrow;
}
pixel *
ppm_mapfiletocolorrow(file, maxcolors, ncolorsP, maxvalP)
FILE *file;
int maxcolors;
int *ncolorsP;
pixval *maxvalP;
{
int cols, rows, format, row, col, ncolors;
pixel *pixrow, *temprow;
colorhash_table cht;
pixrow = ppm_allocrow(maxcolors);
ppm_readppminit(file, &cols, &rows, maxvalP, &format);
temprow = ppm_allocrow(cols);
cht = ppm_alloccolorhash(); ncolors = 0;
for( row = 0; row < rows; row++ ) {
ppm_readppmrow(file, temprow, cols, *maxvalP, format);
for( col = 0; col < cols; col++ ) {
if( ppm_lookupcolor(cht, &temprow[col]) < 0 ) {
if( ncolors >= maxcolors ) {
ppm_freerow(pixrow);
pixrow = (pixel *)0;
ncolors = -1;
goto fail;
}
if( ppm_addtocolorhash(cht, &temprow[col], ncolors) < 0 )
pm_error("out of memory adding to hash table");
pixrow[ncolors] = temprow[col];
++ncolors;
}
}
}
fail:
ppm_freecolorhash(cht);
ppm_freerow(temprow);
*ncolorsP = ncolors;
return pixrow;
}
static int
pixel_cmp(a, b)
void *a, *b;
{
pixel *p1 = (pixel *)a, *p2 = (pixel *)b;
int diff;
diff = PPM_GETR(*p1) - PPM_GETR(*p2);
if( diff == 0 ) {
diff = PPM_GETG(*p1) - PPM_GETG(*p2);
if( diff == 0 )
diff = PPM_GETB(*p1) - PPM_GETB(*p2);
}
return diff;
}
static int (*custom_cmp) ARGS((pixel *, pixel *));
static int
custom_stub(a, b)
void *a, *b;
{
return (*custom_cmp)((pixel *)a, (pixel *)b);
}
void
ppm_sortcolorrow(colorrow, ncolors, cmpfunc)
pixel *colorrow;
int ncolors;
int (*cmpfunc) ARGS((pixel *, pixel *));
{
if( cmpfunc ) {
custom_cmp = cmpfunc;
qsort((void *)colorrow, ncolors, sizeof(pixel), custom_stub);
}
else
qsort((void *)colorrow, ncolors, sizeof(pixel), pixel_cmp);
}
int
ppm_addtocolorrow(colorrow, ncolorsP, maxcolors, pixelP)
pixel *colorrow;
int *ncolorsP;
int maxcolors;
pixel *pixelP;
{
int i;
pixval r, g, b;
r = PPM_GETR(*pixelP);
g = PPM_GETG(*pixelP);
b = PPM_GETB(*pixelP);
for( i = 0; i < *ncolorsP; i++ ) {
if( PPM_GETR(colorrow[i]) == r &&
PPM_GETG(colorrow[i]) == g &&
PPM_GETB(colorrow[i]) == b )
return i;
}
i = *ncolorsP;
if( i >= maxcolors )
return -1;
colorrow[i] = *pixelP;
++*ncolorsP;
return i;
}
int
ppm_findclosestcolor(colormap, ncolors, pP)
pixel *colormap;
int ncolors;
pixel *pP;
{
/* Search colormap for closest match. */
/* algorithm taken from ppmquant.c -IUW */
register int i, r1, g1, b1;
int ind;
long dist;
r1 = PPM_GETR(*pP);
g1 = PPM_GETG(*pP);
b1 = PPM_GETB(*pP);
dist = 2000000000;
for( i = 0; i < ncolors; i++ ) {
register int r2, g2, b2;
long newdist;
r2 = PPM_GETR(colormap[i]);
g2 = PPM_GETG(colormap[i]);
b2 = PPM_GETB(colormap[i]);
newdist = ( r1 - r2 ) * ( r1 - r2 ) +
( g1 - g2 ) * ( g1 - g2 ) +
( b1 - b2 ) * ( b1 - b2 );
if( newdist < dist ) {
ind = i;
dist = newdist;
}
}
return ind;
}
void
#if __STDC__
ppm_colorrowtomapfile(FILE *ofp, pixel *colormap, int ncolors, pixval maxval)
#else
ppm_colorrowtomapfile(ofp, colormap, ncolors, maxval)
FILE *ofp;
pixel *colormap;
int ncolors;
pixval maxval;
#endif
{
int i;
ppm_writeppminit(ofp, ncolors, 1, maxval, 1);
for( i = 0; i < ncolors; i++ )
ppm_writeppmrow(ofp, &colormap[i], 1, maxval, 1);
}